package com.sixfoot.realm;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.sixfoot.domain.User;
import com.sixfoot.service.ServerManager;
import com.sixfoot.service.UserService;

public class UserRealm extends AuthorizingRealm {
	final Logger logger = LoggerFactory.getLogger(UserRealm.class);
	
	@Autowired
	private UserService userService;

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
			throws AuthenticationException {
		if (authcToken == null) {
			throw new AuthenticationException("AuthenticationToken argument cannot be null.");
		}
		
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
		User user = userService.findByUsername(token.getUsername());
//		logger.info("userService: " + userService);
//		logger.info("user: " + user);
		if (user == null || !user.getPassword().equals(new String(token.getPassword())))
			throw new AuthenticationException("用户不存在或未通过认证");
		
		Session session = SecurityUtils.getSubject().getSession();
		session.setAttribute("user", user);		// 将用户信息放入session
		return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
	}

	/**
     * 根据用户身份获取授权信息
     */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		// 根据用户配置用户与权限  
        if (principals == null) {  
            throw new AuthorizationException("PrincipalCollection argument cannot be null.");  
        }
        String username = (String) getAvailablePrincipal(principals);  
        
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();  
        // 增加角色  
        info.addRoles(userService.loadRoles(username));
        // 增加权限 
        info.addStringPermissions(userService.loadPermissions(username));
        return info;
	}

	@Override
	public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
		super.clearCachedAuthorizationInfo(principals);
	}

	@Override
	public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
		super.clearCachedAuthenticationInfo(principals);
	}

	@Override
	public void clearCache(PrincipalCollection principals) {
		super.clearCache(principals);
	}

	public void clearAllCachedAuthorizationInfo() {
		getAuthorizationCache().clear();
	}

	public void clearAllCachedAuthenticationInfo() {
		getAuthenticationCache().clear();
	}

	public void clearAllCache() {
		clearAllCachedAuthenticationInfo();
		clearAllCachedAuthorizationInfo();
	}
}
